#pragma once

#include "nocopy.h"
#include "TimeStamp.h"

#include <functional>
#include <memory>

class EventLoop;
class Channel : nocopyable
{
public:
    typedef std::function<void()> EventCallBack;
    typedef std::function<void(TimeStamp)> ReadEventCallBack;
    Channel(EventLoop *loop, int fd);
    // 事件处理函数
    void handlerEvevt(TimeStamp recvTime);
    void handlerEventWithGuard(TimeStamp receiveTime);

    void ReadCallBack(ReadEventCallBack cb);
    void writeCallBack(EventCallBack cb);
    void errorCallBack(EventCallBack cb);
    void closeCallBack(EventCallBack cb);
    void tie(const std::shared_ptr<void> &obj);
    // 当channel改变fd中的event后，更新epoll里相应的事件

    int fd() const;
    int events() const;
    void set_events(int revt) { revents_ = revt; };

    bool isNoneEvent() const;

    // 设置fd对应状态
    void enableReading();
    void disableReading();
    void enableWriting();
    void disableWriting();

    void disableAll();

    bool isWriting() const;
    bool isReading() const;

    void setindex(int idx);
    int index();
    // 在Channel所属的EventLoop中，删除当前的Channel
    void remove();
    ~Channel();

private:
    void update();

    static const int KnoneEvent_;
    static const int KReadEvent_;
    static const int KWriteEvent_;
    EventLoop *loop_; // 事件循环
    const int fd_;    // poller监听对象
    int events_;      // 注册事件
    int revents_;     // poller返回具体发生的事件
    int index_;

    std::weak_ptr<void> tie_;
    bool tied_;

    EventCallBack writeCallBack_;
    EventCallBack closeCallBack_;
    ReadEventCallBack readCallBack_;
    EventCallBack errorCallBack_;
};
